//
//  QRCodeViewController.swift
//  zyqWeibo
//
//  Created by 张亚琼 on 15/6/29.
//  Copyright © 2015年 张亚琼. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController,UITabBarDelegate,AVCaptureMetadataOutputObjectsDelegate {

    // 冲击波
    @IBOutlet weak var scanImage: UIImageView!
    // 扫描结果显示
    @IBOutlet weak var stringValue: UILabel!
    // 容器的宽度约束
    @IBOutlet weak var widthContraint: NSLayoutConstraint!
    // 容器的高度约束
    @IBOutlet weak var hightConstraint: NSLayoutConstraint!
    // 冲击波的顶部约束
    @IBOutlet weak var topConstraint: NSLayoutConstraint!
   // tabBar
    @IBOutlet weak var tabBar: UITabBar!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 默认选中第一个按钮
        tabBar.selectedItem = tabBar.items![0]
        
        // 设置扫描session
        setUpScanSession()
        // 设置图层
        setUpLayers()
    }
    
    /// 视图已经显示的时候开始动画
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        // 开始动画
        startAnimation()
        
        // 开始扫描
        startScan()
    }
    /// 点击“我的名片”按钮
    @IBAction func myCard() {
        // 直接这样push出来控制器，会有卡顿现象，给控制器view设置背景色就好了
        navigationController?.pushViewController(QRCMyCardViewController(), animated: true)
        
    }
    
    /// 开始扫描
    func startScan() {
        session.startRunning()
    }
    
    /// 开始动画
    func startAnimation() {
        // 动画就是改变冲击波的顶部约束
        // 默认
        topConstraint.constant = -hightConstraint.constant
        view.layoutIfNeeded()
        UIView.animateWithDuration(2.0) { () -> Void in
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.topConstraint.constant = self.hightConstraint.constant
            self.view.layoutIfNeeded()
        }
    }
    
    /// 设置图层
    func setUpLayers() {
        // 设置绘图图层
        drawLayer.frame = view.bounds
        // 放在最底层
        view.layer.insertSublayer(drawLayer, atIndex: 0)
        
        // 设置预览视图图层大小
        previewLayer.frame = view.bounds
        // 设置填充模式
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        // 将图层添加到当前图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        
    }
    
    /// 设置会话
    func setUpScanSession() {
        // 判断能否添加输入设备
        if !session.canAddInput(inputDevice) {
            print("无法加入输入设备")
            return
        }
        if !session.canAddOutput(outputData) {
            print("无法加入输出数据")
            return
        }
        // 如果都可以添加，那就添加呗
        session.addInput(inputDevice)
        session.addOutput(outputData)
        
        // 设置检测数据类型，检测所有支持的数据格式？？
        outputData.metadataObjectTypes = outputData.availableMetadataObjectTypes
        // 设置数据的代理
        outputData.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
    }
    /// 输出数据的代理方法
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        print("进入输出数据的代理方法")
        // 先清空图层
        clearDrawLayer()
        // 遍历所有扫描到的数据
        for object in metadataObjects {
            if object is AVMetadataMachineReadableCodeObject {
                //如果是二维码 转换成数据类型
                let codeObject = previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                drawCorners(codeObject)
                print(codeObject)
                stringValue.text = codeObject.stringValue
            }
        }
    }
    ///  绘制
    private func drawCorners(codeObject: AVMetadataMachineReadableCodeObject) {
        print(codeObject)
        
        // 可以做动画绘图的，专门在图层中画图
        let layer = CAShapeLayer()
        // 线宽
        layer.lineWidth = 4
        // 线的颜色
        layer.strokeColor = UIColor.redColor().CGColor
        // 其他地方没有颜色
        layer.fillColor = UIColor.clearColor().CGColor
        
        // 是一个 包含 CFDictionaries 的 NSArray，四个点
        layer.path = createPath(codeObject.corners).CGPath
        
        drawLayer.addSublayer(layer)
    }
    // 画线
    private func createPath(corners: NSArray) -> UIBezierPath {
        
        let path = UIBezierPath()
        
        // 定义 Point
        var point = CGPoint()
        var index = 0
        // 取到第0个点
        CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
        // 移动到第 0 个点
        path.moveToPoint(point)
        
        // 遍历剩余的点，依次连线
        while index < corners.count {
            // ？？？
            CGPointMakeWithDictionaryRepresentation(corners[index++] as! CFDictionary, &point)
            // 添加路线
            path.addLineToPoint(point)
        }
        
        // 关闭路径
        path.closePath()
        
        return path
    }

    /// 清空图层
    private func clearDrawLayer() {
        // 如果没有子图层，直接返回
        if drawLayer.sublayers == nil {
            return
        }
        // 如果有，全部移除
        for sublayer in drawLayer.sublayers! {
            sublayer.removeFromSuperlayer()
        }
    }
    
   

    // 关闭控制器
    @IBAction func closeController(sender: AnyObject) {
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    /// tabBarDelelgate的代理方法，选中某个按钮
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        hightConstraint.constant = widthContraint.constant * (item.tag == 0 ? 1 : 0.5)
        // 结束动画，再开启动画
        scanImage.layer.removeAllAnimations()
        
        startAnimation()
    }
    
    
    /// 各种懒加载
    
    //1. session桥梁
    lazy var session: AVCaptureSession = AVCaptureSession()
    //2. 输入设备???
    lazy var inputDevice: AVCaptureDeviceInput? = {
       // 摄像头设备!!!注意不要写成AVMediaTypeAudio了
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        
        do {
            return try AVCaptureDeviceInput(device: device)
        } catch {
            print(error)
            return nil
        }
    }()
    
    //3. 输出数据
    lazy var outputData: AVCaptureMetadataOutput = AVCaptureMetadataOutput()
    
    // 4.绘图图层
    lazy var drawLayer:CALayer = CALayer()
    
    // 5.预览视图，是依赖于session的，显示扫描的东西
    // 这种写法也是懒加载，里面的变量也要加self
    lazy var previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.session)
   
}
